﻿using SCG.General;
using SCG.SolarVengeanceEngine;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace SCG.SolarVengeance
{
    public partial class ClassLoaderForm : Form
    {
        //constructor
        public static ClassLoaderForm Instance = null;
        public ClassLoaderForm()
        {
            InitializeComponent();
            Instance = this;
        }

        //main form reference
        public MainForm MainForm { get; set; }

        //access scenarios
        public List<Scenario> Scenarios
        {
            get
            {
                return _scenarios;
            }
        }

        //access previews
        public Dictionary<Scenario, Image> PreviewImages
        {
            get
            {
                return _previews;
            }
        }

        //access brains
        public List<Brain> Brains
        {
            get
            {
                return _brains;
            }
        }

        //load everything!
        public void LoadClasses()
        {
            Font = new Font(MainForm.FontFamily, 14);
            lblLoading.Font = Font;
            lblErrors.Font = Font;
            btnOK.Font = Font;

            //how many items to load?
            string path = Path.GetDirectoryName(Application.ExecutablePath) + "\\Scenarios";
            string[] scenarioFiles = Directory.GetFiles(path);
            path = Path.GetDirectoryName(Application.ExecutablePath) + "\\Brains";
            string[] brainFiles = Directory.GetFiles(path);
            progress.Maximum = scenarioFiles.Length + brainFiles.Length;

            //load scenarios
            SourceCodeCompiler compiler = new SourceCodeCompiler();
            foreach (string fileName in scenarioFiles)
            {
                progress.Value++;
                string scenFile = Path.GetFileNameWithoutExtension(fileName);
                lblLoading.Text = "Loading Scenario " + scenFile;
                lblLoading.Refresh();
                string source = File.ReadAllText(fileName);
                try
                {
                    Scenario scenario = (Scenario)compiler.CompileSource(source, "Scenario", "SCG.SolarVengeanceEngine;SCG.SolarVengeance.exe");
                    if (compiler.CompilerErrors.Count > 0)
                        throw new ArgumentException(compiler.CompilerErrors[0].ErrorText);
                    _scenarios.Add(scenario);
                    Bitmap preview = ScenarioPreviewGenerator.GeneratePreview(scenario, 60, 45);
                    _previews[scenario] = preview;
                }
                catch (Exception ex)
                {
                    txtErrors.Text += "Error in Scenario " + scenFile + ": " + ex.Message + Environment.NewLine;
                }
            }

            //load brains
            foreach (string fileName in brainFiles)
            {
                progress.Value++;
                string brainFile = Path.GetFileNameWithoutExtension(fileName);
                lblLoading.Text = "Loading Brain " + brainFile;
                lblLoading.Refresh();
                string source = File.ReadAllText(fileName);
                try
                {
                    Brain brain = (Brain)compiler.CompileSource(source, "Brain", "SCG.SolarVengeanceEngine");
                    if (compiler.CompilerErrors.Count > 0)
                        throw new ArgumentException(compiler.CompilerErrors[0].ErrorText);
                    _brains.Add(brain);
                    _brainSource[brain] = source;
                }
                catch (Exception ex)
                {
                    txtErrors.Text += "Error in Brain " + brainFile + ": " + ex.Message + Environment.NewLine;
                }
            }

            //auto-shut down or show OK?
            if (txtErrors.Text == "")
                DialogResult = DialogResult.OK;
            else
                btnOK.Visible = true;
        }

        //create new brain instance
        public Brain CloneBrain(Brain brain)
        {
            string source = _brainSource[brain];
            SourceCodeCompiler compiler = new SourceCodeCompiler();
            Brain clone = (Brain)compiler.CompileSource(source, "Brain", "SCG.SolarVengeanceEngine");
            return clone;       
        }

        //private members
        private List<Scenario> _scenarios = new List<Scenario>();
        private Dictionary<Scenario, Image> _previews = new Dictionary<Scenario, Image>();
        private List<Brain> _brains = new List<Brain>();
        private Dictionary<Brain, string> _brainSource = new Dictionary<Brain, string>();

        //load the classes when form is shown
        private void ClassLoaderForm_Shown(object sender, EventArgs e)
        {
            LoadClasses();
        }
    }
}
